package utilities.googleMap;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.logging.Level;
import java.util.logging.Logger;
import utilities.json.JSONArray;
import utilities.json.JSONException;
import utilities.json.JSONObject;
import utilities.json.JSONReader;


/**
 * Classe di utilità per ottenere informazioni geografiche
 * @author Luca Novara
 */
public class DistanceMatrix {
    
    /**
     * Restituisce la lunghezza del percorso tra due luoghi. Si noti che scambiando i 
     * parametri in input la distanza può variare (ad esempio, per via dei sensi unici)
     * @param from indirizzo di partenza
     * @param to indirizzo di destinazione
     * @return la distanza tra gli indirizzi
     */
    public static double distanceFrom(String from, String to) {
        JSONObject distance, reply;
        String f = null;
        String t = null;
        String url;
        
        try {
            f = URLEncoder.encode(from, "UTF-8");
            t = URLEncoder.encode(to, "UTF-8");
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(DistanceMatrix.class.getName()).log(Level.SEVERE, null, ex);
        }
 
        url = "https://maps.googleapis.com/maps/api/distancematrix/json?";
        url += "origins=" + f + "&";
        url += "destinations=" + t + "&";
        url += "sensor=false";
        
        try {
            reply = JSONReader.readJSONFromUrl(url);
            
            if (!reply.getString("status").equals("OK"))
                return Double.POSITIVE_INFINITY;
            
            distance = reply.getJSONArray("rows").getJSONObject(0).
                    getJSONArray("elements").getJSONObject(0).
                    getJSONObject("distance");
            
            return distance.getDouble("value");
        } catch (Exception e) {
            return Double.POSITIVE_INFINITY;
        }
    }
    
    /**
     * Restituisce il comune di appartenenza di un certo indirizzo
     * @param address indirizzo di cui determinare il comune
     * @return il comune in cui si trova l'indirizzo in input
     */
    public static String getLocality(String address) {
        JSONArray addressComponents;
        JSONObject ac, reply;
        String a = null;
        String locality = "";
        String url;
        
        try {
            a = URLEncoder.encode(address, "UTF-8");
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(DistanceMatrix.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        url = "https://maps.googleapis.com/maps/api/geocode/json?";
        url += "address=" + a + "&";
        url += "language=it-IT&";
        url += "sensor=false";
        
        try {
            reply = JSONReader.readJSONFromUrl(url);
            
            if (!reply.getString("status").equals("OK"))
                return "";
            
            addressComponents = reply.getJSONArray("results").getJSONObject(0).
                    getJSONArray("address_components");
            
            for (int i = 0; i < addressComponents.length(); i++) {
                ac = addressComponents.getJSONObject(i);
                if (ac.getJSONArray("types").getString(0).equals("locality")) {
                    locality = ac.getString("long_name");
                    break;
                }
            }
        } catch (IOException ex) {
            Logger.getLogger(DistanceMatrix.class.getName()).log(Level.SEVERE, null, ex);
        } catch (JSONException ex) {
            Logger.getLogger(DistanceMatrix.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        return locality;
    }

}